package di.module;

import android.text.TextUtils;

import com.f2prateek.rx.preferences2.RxSharedPreferences;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.http.HttpAgent;
import net.http.LiveNetworkMonitor;
import net.http.NetworkMonitor;
import net.http.NoNetworkException;
import net.http.SSLSocketClient;
import net.http.adapter.NullStringToEmptyAdapterFactory;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.inject.Named;
import javax.inject.Singleton;

import app.OkApplication;
import dagger.Module;
import dagger.Provides;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Authenticator;
import okhttp3.Cache;
import okhttp3.Credentials;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.mock.MockRetrofit;
import retrofit2.mock.NetworkBehavior;
@Module
public  class NetWorkModule {

    @Provides
    @Singleton
    public static Cache provideCache(OkApplication context) {
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache  = new Cache(context.getCacheDir(), cacheSize);
        return cache;
    }
    @Provides
        //@Singleton
    static Retrofit provideRetrofit(OkHttpClient okHttpClient,@Named("domain") String domain) {
        Gson gson = new GsonBuilder()
                .registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory<>())
                .create();
        return new Retrofit.Builder()
                .baseUrl(domain)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addConverterFactory(ScalarsConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
                .build();
    }


    @Provides
        //@Singleton
    static MockRetrofit provideMockRetrofit(Retrofit retrofit) {
        NetworkBehavior behavior = NetworkBehavior.create();
        MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
                .networkBehavior(behavior)
                .build();
        return mockRetrofit;
    }

    @Provides
        //@Singleton
    static  OkHttpClient provideOkHttpClient(Cache cache
                                     //, ClearableCookieJar cookieJar
            //,@Named("tokenAgentInterceptor")Interceptor tokenAgentInterceptor
            ,final OkApplication diApplication
            ,final NetworkMonitor networkMonitor) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .authenticator(new Authenticator() {
                    @Override
                    public Request authenticate(Route route, Response response) throws IOException {
                        String credential = Credentials.basic("client", "secret");
                        //String _token =mRxSharedPreferences.getString(AuthManager.Token).get();
                       /*Auth authRsp= AuthManager.getAuth();
                        if (authRsp!=null && !TextUtils.isEmpty(authRsp.getAccessToken())){
                            return response.request().newBuilder()
                                    .header("Authorization", "Bearer  "+authRsp.getAccessToken())
                                    .build();
                        }*/
                        return response.request().newBuilder()
                                .header("Authorization", credential)
                                .build();
                    }
                })
                .connectTimeout(15, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .readTimeout(30, TimeUnit.SECONDS)
                .cache(cache)
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                // .cookieJar(cookieJar)
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        boolean connected = networkMonitor.isConnected();
                        if (connected) {
                            try{
                                return chain.proceed(chain.request());
                            }catch (IOException e){
                                throw new NoNetworkException(e.getMessage());
                            }
                        } else {
                            throw new NoNetworkException("无网络连接");
                        }
                    }
                })
                 .addInterceptor(new Interceptor() {
                     @Override
                     public Response intercept(Chain chain) throws IOException {
                         Response originalResponse = chain.proceed(chain.request());
                         //String body=originalResponse.body().string();
                        /* Rsp rsp=new Gson().fromJson(body, Rsp.class);
                         if (Rsp.invalid_token.equals(rsp.getError())){
                             Toast.makeText(diApplication, rsp.getError(), Toast.LENGTH_SHORT).show();
                             return originalResponse.newBuilder().body(new ResponseBody() {
                                 @Nullable
                                 @Override
                                 public MediaType contentType() {
                                     return null;
                                 }

                                 @Override
                                 public long contentLength() {
                                     return 0;
                                 }

                                 @Override
                                 public BufferedSource source() {
                                     return null;
                                 }
                             }).build();
                         }else{*/
                             return originalResponse.newBuilder()
                                     //.header("Cache-Control", "max-age=60")
                                     .build();
                         //}
                     }
                 })
                //.addInterceptor(tokenAgentInterceptor)
                //.addInterceptor(new HttpLoggingInterceptor().setLevel(BuildConfig.DEBUG? HttpLoggingInterceptor.Level.BODY: HttpLoggingInterceptor.Level.NONE))
                .build();

        return okHttpClient;
    }


    @Provides
        //@Singleton
    static NetworkMonitor provideNetworkMonitor(OkApplication context) {
        return new LiveNetworkMonitor(context);
    }

    @Provides
    //@Singleton
    @Named("userAgent")
    static String provideUserAgent(OkApplication context) {
        return HttpAgent.getUserAgent(context);
    }


   /* @Provides
    //@Singleton
    @Named("tokenAgentInterceptor")
    Interceptor provideTokenAgentInterceptor(final @Named("userAgent") String userAgent,final RxSharedPreferences mRxSharedPreferences) {
        return  new Interceptor(){
            @Override
            public Response intercept(final Chain chain) throws IOException {
                Request originalRequest = chain.request();
                String method= originalRequest.method();
                Request.Builder requestBuilder = originalRequest.newBuilder();

                //Auth authRsp= AuthManager.getAuth();
                //requestBuilder.header("Authorization", "Bearer "+authRsp.getAccessToken());
                //User-Agent: okhttp/3.8.0
                requestBuilder.header("User-Agent",userAgent);
                //requestBuilder.addHeader("Content-Type", "application/json;charset=UTF-8");
                requestBuilder.header("Connection","close");
                //form
                if("POST".equals(method) && originalRequest.body() instanceof FormBody){
                    FormBody formBody= (FormBody) originalRequest.body();
                    FormBody.Builder newFormBody = new FormBody.Builder();
                    for (int i = 0; i <formBody.size() ; i++) {
                        newFormBody.addEncoded(formBody.encodedName(i),formBody.encodedValue(i));
                    }
                    *//*if (!TextUtils.isEmpty(_token)
                            &&
                            !originalRequest.url().toString().contains("getVcodeToken")){
                        newFormBody.add("token",_token);
                    }*//*
                    requestBuilder.method(method,newFormBody.build());
                  try {
                      return chain.proceed(requestBuilder.build());
                  }catch (Exception e){
                      throw new NoNetworkException(e.getMessage());
                  }
                }

                HttpUrl originalHttpUrl = originalRequest.url();
                HttpUrl.Builder _builder= originalHttpUrl.newBuilder()
                        .addQueryParameter("client","android");
                if (!TextUtils.isEmpty(_token)
                        &&
                        !originalRequest.url().toString().contains("getVcodeToken")) {
                    _builder.addQueryParameter("token", _token);
                }

                Request request = requestBuilder
                        .url(_builder.build())
                        .method(originalRequest.method(), originalRequest.body())
                        .build();

                try {
                    return chain.proceed(requestBuilder.build());
                }catch (Exception e){
                    throw new NoNetworkException(e.getMessage());
                }

               try {
                   return chain.proceed(chain.request());
               }catch (Exception e){
                   throw new NoNetworkException(e.getMessage());
               }
            }
        };
    }
*/
  /*  @Provides
    @Singleton
    ClearableCookieJar provideCookieJar(DIApplication application) {
        ClearableCookieJar cookieJar =
                new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(application));
        return cookieJar;
    }*/

    @Provides
    @Singleton
    @Named("domain")
    static String  providesDomain() {
        return "http://192.168.1.5:8090";
    }
}
